﻿using Component.Track;
using Component.Trains;
using Component.UI.Tools;
using Config;
using Tools;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Component.UI.View
{
    public class GameView : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
    {
        [Header("可用火车数")]
        public GameObject[] gos;
        public int CurrentCount { get; set; }
        public bool Clicking { get; private set; }
        
        private DrawMeshTools modelMesh;
        
        private void Awake()
        {
            GameObject go = new GameObject("ui tools");
            modelMesh = go.AddComponent<DrawMeshTools>();
            modelMesh.SortLayer = 5;
            modelMesh.transform.localScale = Vector3.zero;
        }

        private void Start()
        {
            RectTransform[] children = transform.GetComponentsInChildren<RectTransform>();
            gos = new GameObject[children.Length - 1];
            for (int i = 0; i < children.Length - 1; i++)
            {
                gos[i] = children[i + 1].gameObject;
            }

            CurrentCount = children.Length;
            
            modelMesh.DrawTrain(modelMesh.transform.position, 0.7f * 2,1.34f * 2, new Color(.5f, .5f, .5f, .5f));
            
            modelMesh.gameObject.SetActive(false);
            modelMesh.EnableAction += () =>
            {
                transform.localRotation = Quaternion.Euler(0,0,0);
                modelMesh.transform.localScale = Vector3.zero;
                LeanTween.scale(modelMesh.gameObject, Vector3.one, .25f).setDelay(.1f).setEase(LeanTweenType.easeOutBounce);
            };
        }

        private void Update()
        {
            if (CurrentCount < 1)
            {
                return;
            }
            for (int i = CurrentCount - 1; i < gos.Length; i++)
            {
                if (gos[i].activeSelf)
                {
                    gos[i].SetActive(false);
                }
            }
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            if (CurrentCount < 1)
            {
                Clicking = false;
                return;
            }

            Clicking = true;
            
            CurrentCount--;
            modelMesh.transform.position = CameraTools.ScreenToWorldPoint(eventData.position);

            modelMesh.gameObject.SetActive(true);
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            Clicking = false;
            
            modelMesh.gameObject.SetActive(false);
            
            if (result.DragOnLine)
            {
                Train train = new Train(result.StartPos, result.Angle, result.Color, result.LineId);
                result = new DragResult();
            }
            else if(CurrentCount > 0)
            {
                gos[CurrentCount - 1].SetActive(true);
                CurrentCount++;
            }
        }


        private Vector3 lastPoint = Vector3.zero;
        public void OnDrag(PointerEventData eventData)
        {
            if (CurrentCount < 1)
            {
                return;
            }
            
            modelMesh.transform.position = CameraTools.ScreenToWorldPoint(eventData.position);

            CheckLine(eventData.position);
        }

        private void CheckLine(Vector2 position)
        {
            int angle = 0;
            Ray ray = CameraTools.ScreenRayHitInfo(position);
            if (Physics.Raycast(ray,out var hitInfo, Mathf.Infinity, LayerTools.LineLayerMask))
            {
                Vector3 direction = (ray.origin - lastPoint);
                while (angle <= 135)
                {
                    if (Physics.Raycast(ray.origin + new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 
                        Mathf.Sin(angle * Mathf.Deg2Rad)), ray.direction, Mathf.Infinity, LayerTools.LineLayerMask))
                    {
                        if (direction.x < 0 || direction.y < 0)
                        {
                            angle += 180;
                        }

                        lastPoint = ray.origin;
                        break;
                    }

                    angle += 45;
                }
                result = new DragResult(true, Line.GetLineColor(hitInfo.transform.gameObject.GetInstanceID()), ray.origin, Quaternion.Euler(0,0,angle), hitInfo.transform.gameObject.GetInstanceID());
            }
            else
            {
                result = new DragResult();
            }
            modelMesh.transform.localRotation = Quaternion.Euler(0, 0, angle);
        }

        private readonly struct DragResult
        {
            public readonly bool DragOnLine;
            public readonly Color Color;
            public readonly Vector2 StartPos;
            public readonly Quaternion Angle;
            public readonly int LineId;

            public DragResult(bool dragOnLine, Color color, Vector2 startPos, Quaternion angle, int id)
            {
                DragOnLine = dragOnLine;
                Color = color;
                StartPos = startPos;
                Angle = angle;
                LineId = id;
            }
        }

        private DragResult result;
    }

    
    // public class GameUiTools
    // {
    //     public static GameUiTools Instance { get;}
    //     public GameUiManager uiManager { get; }
    //
    //     public GameUiTools()
    //     {
    //         GameObject go = GameObject.Find("Trains");
    //         uiManager = go.AddComponent<GameUiManager>();
    //     }
    //
    //     static GameUiTools()
    //     {
    //         Instance = new GameUiTools();
    //     }
    // }
}